<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Funqy</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/funqy" />
  <meta property="og:title" content="Quarkus - Funqy" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/funqy">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Funqy</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#funqy-basics">Funqy Basics</a></li>
<li><a href="#async-reactive-types">Async Reactive Types</a></li>
<li><a href="#function-names">Function Names</a></li>
<li><a href="#funqy-di">Funqy DI</a></li>
<li><a href="#context-injection">Context injection</a></li>
<li><a href="#should-i-use-funqy">Should I Use Funqy?</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Quarkus Funqy is part of Quarkus&#8217;s serverless strategy and aims to provide a portable Java API to write functions
deployable to various FaaS environments like AWS Lambda, Azure Functions, Knative, and Knative Events (Cloud Events).  It is also
usable as a standalone service.</p>
</div>
<div class="paragraph">
<p>Because Funqy is an abstraction that spans multiple different cloud/function providers
and protocols it has to be a very simple API and thus, might not have all the features you are used
to in other remoting abstractions.  A nice side effect though is that Funqy is as optimized and
as small as possible.  This means that because Funqy sacrifices a little bit on flexibility, you&#8217;ll
get a framework that has little to no overhead.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="funqy-basics"><a class="anchor" href="#funqy-basics"></a>Funqy Basics</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Funqy API is simple.  Annotate a method with <code>@Funq</code>.  This method may only have one optional input parameter
and may or may not return a response.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import io.quarkus.funqy.Funq;

public class GreetingFunction {
    @Funq
    public String greet(String name) {
       return "Hello " + name;
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Java classes can also be used as input and output and must follow the Java bean convention and have
a default constructor.  The Java type that is declared as the parameter or return type is the type that will be
expected by the Funqy runtime.  Funqy does type introspection at build time to speed up boot time, so any derived types
will not be noticed by the Funqy marshalling layer at runtime.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example of using a POJO as input and output types.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public class GreetingFunction {
    public static class Friend {
        String name;

        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
    }

    public static class Greeting {
        String msg;

        public Greeting() {}
        public Greeting(String msg) { this.msg = msg }

        public String getMessage() { return msg; }
        public void setMessage(String msg) { this.msg = msg; }
    }

    @Funq
    public Greeting greet(Friend friend) {
       return new Greeting("Hello " + friend.getName());
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="async-reactive-types"><a class="anchor" href="#async-reactive-types"></a>Async Reactive Types</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Funqy supports the <a href="https://smallrye.io/smallrye-mutiny">Smallrye Mutiny</a> <code>Uni</code> reactive type as a return type.  The only requirement is that
the <code>Uni</code> must fill out the generic type.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import io.quarkus.funqy.Funq;
import io.smallrye.mutiny.Uni;

public class GreetingFunction {

    @Funq
    public Uni&lt;Greeting&gt; reactiveGreeting(String name) {
       ...
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="function-names"><a class="anchor" href="#function-names"></a>Function Names</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The function name defaults to the method name and is case sensitive.  If you want your function referenced by a different name,
parameterize the <code>@Funq</code> annotation as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import io.quarkus.funqy.Funq;

public class GreetingFunction {

    @Funq("HelloWorld")
    public String greet(String name) {
       return "Hello " + name;
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="funqy-di"><a class="anchor" href="#funqy-di"></a>Funqy DI</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Each Funqy Java class is a Quarkus Arc component and supports dependency injection through
CDI or Spring DI.  Spring DI requires including the <code>quarkus-spring-di</code> dependency in your build.</p>
</div>
<div class="paragraph">
<p>The default object lifecycle for a Funqy class is <code>@Dependent</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import io.quarkus.funqy.Funq;

import javax.inject.Inject;
import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class GreetingFunction {

    @Inject
    GreetingService service;

    @Funq
    public Greeting greet(Friend friend) {
        Greeting greeting = new Greeting();
        greeting.setMessage(service.greet(friend.getName()));
        return greeting;
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="context-injection"><a class="anchor" href="#context-injection"></a>Context injection</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Funqy API will usually not allow you to inject or use abstractions that
are specific to a protocol (i.e. HTTP) or function API (i.e. AWS Lambda).  There are
exceptions to the rule though and you may be able to inject
contextual information that is specific to the environment you are deploying in.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
We do not recommend injecting contextual information specific to a runtime.  Keep your functions portable.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Contextual information is injected via the <code>@Context</code> annotation which can be used on a function parameter
or a class field.  A good example is the <code>CloudEvent</code> interface that comes with our Funqy
Knative Cloud Events integration:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import io.quarkus.funqy.Funq;
import io.quarkus.funqy.Context;

public class GreetingFunction {

    @Funq
    public Greeting greet(Friend friend, @Context CloudEvent eventInfo) {
        System.out.println("Received greeting request from: " eventInfo.getSource());

        Greeting greeting = new Greeting();
        greeting.setMessage("Hello " + friend.getName()));
        return greeting;
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="should-i-use-funqy"><a class="anchor" href="#should-i-use-funqy"></a>Should I Use Funqy?</h2>
<div class="sectionbody">
<div class="paragraph">
<p>REST over HTTP has become a very common way to write services over the past decade.  While Funqy
has an HTTP binding it is not a replacement for REST.  Because Funqy has to work across a variety
of protocols and function cloud platforms, it is very minimalistic and constrained.  For example, if you
use Funqy you lose the ability to link (think URIs) to the data your functions spit out.  You also
lose the ability to leverage cool HTTP features like <code>cache-control</code> and conditional GETs.  Many
developers will be ok with that as many won&#8217;t be using these REST/HTTP features or styles. You&#8217;ll
have to make the decision on what camp you are in.  Quarkus does support REST integration (through JAX-RS,
 Spring MVC, Vert.x Web, and Servlet) with
various cloud/function providers, but there are some disadvantages of using that approach as well.  For example,
if you want to do <a href="amazon-lambda-http">HTTP with AWS Lambda</a>, this requires you to use the AWS API Gateway which may
slow down deployment and cold start time or even cost you more.</p>
</div>
<div class="paragraph">
<p>The purpose of Funqy is to allow you to write cross-provider functions so that you can move
off of your current function provider if, for instance, they start charging you a lot more for their
service.  Another reason you might not want to use Funqy is if you need access specific APIs of the
target function environment.  For example, developers often want access to the AWS Context on
Lambda.  In this case, we tell them they may be better off using the <a href="amazon-lambda">Quarkus Amazon Lambda</a> integration instead.</p>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
